An exploration of dingo observations in the ALA

Time-series analyses can be handy for seeing trends over time, and exploring how trends relate to major events. Here, we show how to create an exploratory time-series plot comparing observations of waterbirds prior to and during the COVID-19 pandemic.

Eukaryota
Animalia
Mammalia
Summaries
Maps
Intern-post
Authors

Amos Smith

Dax Kellie

Published

April 4, 2023

Author

Amos Smith Olivia Torresan
Dax Kellie

Date

4 April 2023

Intern Post

The dingo is among Australia’s most recognised species internationally. However, debate continues on whether dingoes are considered pests or protected native species.

Dingoes have had major negative impacts on livestock producers, especially sheep farmers. To reduce this impact, landowners and government spend an estimated ~$30 million annually across Australia to control wild dog and dingo populations. Populations are often controlled using traps, baits and shooting. Australia also constructed the Dingo Fence, a wire fence made to protect from the loss of sheep for the sheep industry; it is the longest fence in the world (5,614 km).

Since its construction 80 years ago, the Dingo Fence has shaped the landscape of Australia. Perhaps unintentionally, the dingo fence has acted as a natural experiment that has shown the importance of apex predators like dingoes in ecosystems. On the side where dingoes remain present there is more vegetation and fewer invasive species like foxes than on the side where dingoes are absent, benefiting native biodiversity. The difference between sides of the fence is so distinct that you can even see it from space!

Historical and current control programs along with habitat loss have impacted dingo populations negatively, despite evidence that dingoes can be allies for livestock producers. Dingoes are currently listed as vulnerable to extinction under the IUNC’s Red List of Threatened Species.

In an exploratory analysis, here we’ll use data in the Atlas of Living Australia (ALA) to investigate how historical and ongoing differences in attitudes towards dingo conservation affect where and how often dingo observations are recorded.

Summarise observations

Let’s start by seeing how many observations of dingoes are in the ALA and where they are.

# packages
library(galah)
library(tidyverse)
library(ozmaps)
library(sf)
library(patchwork)
library(here)
library(rmapshaper)
library(ggpointdensity)
library(glue)
library(ggtext)

Find which fields to use

We’ll use the {galah} package to download our data. Because Canis familiaris is the taxonomic name of both dingoes and dogs, if we only search using the scientific name, we’ll likely return more than just dingo records. To fix this, let’s filter our records to those specified by the data provider with the name common name “Dingo”.

One can imagine that sometimes data might be collected without specifying the name “Dingo” (either due to uncertainty or a lack of specificity in the survey), which, if true, suggests there might be observations of dingoes that were observed but never recorded in the data (though it’s hard to know for sure)

Let’s use search_fields() to help us find which fields we can use to filter the taxonomic name. There are a few options, but the raw_vernacularName field seems to hold original common names specified by data providers.

search_fields("common name")
# A tibble: 4 × 4
  id                   description                                   type  link 
  <chr>                <chr>                                         <chr> <chr>
1 common_name_and_lsid Concatenation of common name and LSID, usefu… fiel… <NA> 
2 vernacularName       The common name the ALA has matched this rec… fiel… <NA> 
3 names_and_lsid       Concatenation of common name and LSID, usefu… fiel… <NA> 
4 raw_vernacularName   The original common name value supplied by t… fiel… <NA> 
search_fields("raw_vernacularName") |> search_values("dingo")
# A tibble: 4 × 2
  field              category           
  <chr>              <chr>              
1 raw_vernacularName Dingo, domestic dog
2 raw_vernacularName Dingo              
3 raw_vernacularName Dingo & Dog (feral)
4 raw_vernacularName dingo              

We can use the same method to find a field that contains states & territories.

search_fields("australian states")
# A tibble: 2 × 4
  id     description                                                 type  link 
  <chr>  <chr>                                                       <chr> <chr>
1 cl2013 ASGS Australian States and Territories Australian Statisti… laye… http…
2 cl22   Australian States and Territories Australian States and Te… laye… http…
search_fields("cl22") |> show_values()
# A tibble: 11 × 2
   field category                    
   <chr> <chr>                       
 1 cl22  New South Wales             
 2 cl22  Victoria                    
 3 cl22  Queensland                  
 4 cl22  South Australia             
 5 cl22  Western Australia           
 6 cl22  Northern Territory          
 7 cl22  Australian Capital Territory
 8 cl22  Tasmania                    
 9 cl22  Unknown1                    
10 cl22  Ashmore and Cartier Islands 
11 cl22  Coral Sea Islands           

State observations

We’ll download the number of dingo observations in each state/territory with atlas_counts() and arrange the resulting counts in descending order.

Around 75% of dingo observations are recorded in the Northern Territory and South Australia.

dingo_counts <- galah_call() |>
  galah_identify("canis familiaris") |>
  galah_filter(raw_vernacularName == c("Dingo", "dingo")) |>
  galah_group_by(cl22) |>
  # galah_apply_profile(ALA) |> # set of data quality filters
  atlas_counts() |>
  arrange(desc(count))
# A tibble: 7 × 2
  cl22                         count
  <chr>                        <int>
1 Northern Territory            6155
2 South Australia               2933
3 Queensland                    1283
4 New South Wales               1110
5 Victoria                       412
6 Western Australia              130
7 Australian Capital Territory     4
Code
# Add map of australia
aus <- ozmap_data(data = "states")

# Join state counts to our map
state_counts <- aus %>%
  full_join(dingo_counts, by = c("NAME" = "cl22"))

# log-transform data to scale counts for nicer plotting
logged_counts <- state_counts |>
  mutate(log = log10(count))|>
  replace_na(list(log = 0))

# plot
ggplot() +
  geom_sf(data = logged_counts,
          mapping = aes(fill = log)) +
  geom_sf_text(data = logged_counts,
               aes(label = count),
               colour = "white",
               size = 8,
               fun.geometry = sf::st_centroid) +
  scale_fill_distiller(palette = "OrRd", direction = 1) +
  labs(x = "Longitude", y = "Latitude") +
  theme_void() + 
  theme(legend.position = "none")

Data providers

Next let’s find out who the main data providers are of dingo observations to see whether observations come from citizen science programs or state monitoring programs. We’ll filter to only display providers that have provided more than 5 observations of dingoes.

data_providers <- galah_call() |>
  galah_identify("canis familiaris") |>
  galah_filter(raw_vernacularName == c("Dingo", "dingo")) |>
  galah_group_by(dataResourceName)|>
  galah_apply_profile(ALA) |>
  atlas_counts()

counts_filtered <- data_providers |>
  filter(count > 5)
# A tibble: 9 × 2
  dataResourceName                                           count
  <chr>                                                      <int>
1 Fauna Atlas N.T.                                            4867
2 SA Fauna (BDBSA)                                            2832
3 Australian National Wildlife Collection provider for OZCAM  2035
4 WildNet - Queensland Wildlife Data                          1120
5 NSW BioNet Atlas                                            1053
6 Victorian Biodiversity Atlas                                 101
7 Australian Museum provider for OZCAM                          76
8 Museums Victoria provider for OZCAM                           36
9 Northern Gulf Fauna Survey                                    18

We can also check to see where each data provider’s observations are recorded. We’ll download dingo observations using atlas_occurrences(). Then we’ll filter our observations to only those supplied by providers in counts_filtered.

You will need to first provide a registered email with the ALA using galah_config() before retrieving records.

dingo_obs <- galah_call()|>
  galah_identify("canis familiaris") |>
  galah_filter(raw_vernacularName == c("Dingo", "dingo")) |>
  galah_apply_profile(ALA) |>
  atlas_occurrences()
# A tibble: 12,155 × 8
   decimal…¹ decim…² eventDate           scien…³ taxon…⁴ recor…⁵ dataR…⁶ occur…⁷
       <dbl>   <dbl> <dttm>              <chr>   <chr>   <chr>   <chr>   <chr>  
 1     -39      146. NA                  Canis … https:… 902931… Museum… PRESENT
 2     -39      146. NA                  Canis … https:… e8fc34… Museum… PRESENT
 3     -39      146. NA                  Canis … https:… 091e59… Museum… PRESENT
 4     -38.6    143. 1866-03-26 13:55:08 Canis … https:… 13bd89… Victor… PRESENT
 5     -38.4    146. NA                  Canis … https:… 5b05ba… Museum… PRESENT
 6     -38.4    144. 1864-12-31 13:55:08 Canis … https:… c9f581… Victor… PRESENT
 7     -38.4    143. 1886-08-31 13:55:08 Canis … https:… 4cf713… Victor… PRESENT
 8     -38.4    146. NA                  Canis … https:… 8ef4ea… Museum… PRESENT
 9     -38.1    142. 1886-01-22 13:55:08 Canis … https:… 7deaea… Victor… PRESENT
10     -38.1    146. 1973-04-12 14:00:00 Canis … https:… 00a9e4… Austra… PRESENT
# … with 12,145 more rows, and abbreviated variable names ¹​decimalLatitude,
#   ²​decimalLongitude, ³​scientificName, ⁴​taxonConceptID, ⁵​recordID,
#   ⁶​dataResourceName, ⁷​occurrenceStatus
points_filtered <- dingo_obs |>
  filter(dataResourceName %in% counts_filtered$dataResourceName)
# A tibble: 12,138 × 8
   decimal…¹ decim…² eventDate           scien…³ taxon…⁴ recor…⁵ dataR…⁶ occur…⁷
       <dbl>   <dbl> <dttm>              <chr>   <chr>   <chr>   <chr>   <chr>  
 1     -39      146. NA                  Canis … https:… 902931… Museum… PRESENT
 2     -39      146. NA                  Canis … https:… e8fc34… Museum… PRESENT
 3     -39      146. NA                  Canis … https:… 091e59… Museum… PRESENT
 4     -38.6    143. 1866-03-26 13:55:08 Canis … https:… 13bd89… Victor… PRESENT
 5     -38.4    146. NA                  Canis … https:… 5b05ba… Museum… PRESENT
 6     -38.4    144. 1864-12-31 13:55:08 Canis … https:… c9f581… Victor… PRESENT
 7     -38.4    143. 1886-08-31 13:55:08 Canis … https:… 4cf713… Victor… PRESENT
 8     -38.4    146. NA                  Canis … https:… 8ef4ea… Museum… PRESENT
 9     -38.1    142. 1886-01-22 13:55:08 Canis … https:… 7deaea… Victor… PRESENT
10     -38.1    146. 1973-04-12 14:00:00 Canis … https:… 00a9e4… Austra… PRESENT
# … with 12,128 more rows, and abbreviated variable names ¹​decimalLatitude,
#   ²​decimalLongitude, ³​scientificName, ⁴​taxonConceptID, ⁵​recordID,
#   ⁶​dataResourceName, ⁷​occurrenceStatus

We’ll create a bar plot and a map of observations to visualise where dingoes are seen and who records them.

Just five data providers account for ~98% of dingo records, with Fauna Atlas N. T. contributing ~40% of records. All major data providers are government monitoring programs, rather than citizen science providers like iNaturalist.

Code
counts_filtered %>%
  ggplot(aes(x = reorder(str_wrap(dataResourceName, 28), count), 
             y = count, fill = dataResourceName)) +
    geom_bar(stat="identity", width=.8) +
    scale_fill_manual(values = c(
    "Museums Victoria provider for OZCAM" = "#604830", 
    "Victorian Biodiversity Atlas" = "#486030", 
    "Australian National Wildlife Collection provider for OZCAM" = "#6090d8", 
    "NSW BioNet Atlas" = "#604830", 
    "WildNet - Queensland Wildlife Data" = "#6fab3f",
    "SA Fauna (BDBSA)" = "#d89060", 
    "Australian Museum provider for OZCAM" = "#FFC300", 
    "Fauna Atlas N.T." = "#a84830")) +
  scale_x_discrete(expand = c(0,0)) +
  scale_y_continuous(labels = scales::label_comma()) +
    coord_flip() +
    xlab("") +
    pilot::theme_pilot(grid = "v",
                       axes = "b") + 
  theme(legend.position = "none",
        axis.text = element_text(size = 12))
# bar_plot

ggplot() +
  geom_sf(data = aus, fill = "#FBFBEF") +
  geom_point(data = points_filtered,
             mapping = aes(x = decimalLongitude,
                           y = decimalLatitude,
                           colour = dataResourceName),
             alpha = 0.25) +
  scale_color_manual(values = c(
    "Museums Victoria provider for OZCAM" = "#604830", 
    "Victorian Biodiversity Atlas" = "#486030", 
    "Australian National Wildlife Collection provider for OZCAM" = "#6090d8",
    "NSW BioNet Atlas" = "#604830", 
    "WildNet - Queensland Wildlife Data" = "#6fab3f",
    "SA Fauna (BDBSA)" = "#d89060", 
    "Australian Museum provider for OZCAM" = "#FFC300", 
    "Fauna Atlas N.T." = "#a84830")) +
  theme_void() +
  coord_sf(ylim = c(-45, -10), 
           xlim = c(110, 155)) +
  theme(legend.position = "none")
# # Plot bar plot and map
# bar_plot + data_providers + 
#   plot_annotation(
#     title = "Data Providers of Dingo Observations"
#   ) + 
#   plot_layout(widths = c(1, 3),
#               heights = c(2, 1))

Government monitoring programs provide regular and reliable data. However, incidental observations from citizen scientists can fill gaps in species distribution data.

It’s also possible that differences between states/territories attitudes towards dingoes and their conservation status between states/territories affect the amount of data recorded of dingo observations. For example, the Northern Territory is the only state in Australia that recognizes dingoes as a protected species. Other states like Western Australia, New South Wales, Queensland and South Australia consider dingoes outside the Dog Fence an unprotected native animal and inside the Dingo Fence a pest species under the National Parks and Wildlife Act 1972. These differences in legislation between states might help to explain why the highest numbers of observations are in areas that recognize dingoes as protected.

Expand for session info
─ Session info ───────────────────────────────────────────────────────────────
 setting  value
 version  R version 4.2.2 (2022-10-31 ucrt)
 os       Windows 10 x64 (build 19044)
 system   x86_64, mingw32
 ui       RTerm
 language (EN)
 collate  English_Australia.utf8
 ctype    English_Australia.utf8
 tz       Australia/Sydney
 date     2023-04-11
 pandoc   2.19.2 @ C:/Program Files/RStudio/resources/app/bin/quarto/bin/tools/ (via rmarkdown)

─ Packages ───────────────────────────────────────────────────────────────────
 package        * version date (UTC) lib source
 dplyr          * 1.1.0   2023-01-29 [1] CRAN (R 4.2.2)
 forcats        * 1.0.0   2023-01-29 [1] CRAN (R 4.2.2)
 galah          * 1.5.2   2023-03-20 [1] Github (AtlasOfLivingAustralia/galah@1b35520)
 ggplot2        * 3.4.1   2023-02-10 [1] CRAN (R 4.2.2)
 ggpointdensity * 0.1.0   2019-08-28 [1] CRAN (R 4.2.1)
 ggtext         * 0.1.2   2022-09-16 [1] CRAN (R 4.2.2)
 glue           * 1.6.2   2022-02-24 [1] CRAN (R 4.2.1)
 here           * 1.0.1   2020-12-13 [1] CRAN (R 4.2.1)
 htmltools      * 0.5.4   2022-12-07 [1] CRAN (R 4.2.2)
 lubridate      * 1.9.2   2023-02-10 [1] CRAN (R 4.2.2)
 ozmaps         * 0.4.5   2021-08-03 [1] CRAN (R 4.2.1)
 patchwork      * 1.1.2   2022-08-19 [1] CRAN (R 4.2.1)
 purrr          * 1.0.1   2023-01-10 [1] CRAN (R 4.2.2)
 readr          * 2.1.4   2023-02-10 [1] CRAN (R 4.2.2)
 rmapshaper     * 0.4.6   2022-05-10 [1] CRAN (R 4.2.1)
 sessioninfo    * 1.2.2   2021-12-06 [1] CRAN (R 4.2.1)
 sf             * 1.0-9   2022-11-08 [1] CRAN (R 4.2.2)
 stringr        * 1.5.0   2022-12-02 [1] CRAN (R 4.2.2)
 tibble         * 3.1.8   2022-07-22 [1] CRAN (R 4.2.1)
 tidyr          * 1.3.0   2023-01-24 [1] CRAN (R 4.2.2)
 tidyverse      * 2.0.0   2023-02-22 [1] CRAN (R 4.2.2)

 [1] C:/Users/KEL329/R-packages
 [2] C:/Users/KEL329/AppData/Local/Programs/R/R-4.2.2/library

──────────────────────────────────────────────────────────────────────────────